﻿#region Using Directives

    using System;  

    using Csla;

    using MarketPulse.BusinessLogic.Core;
    using MarketPulse.BusinessLogic.Common.Criteria;

#endregion

namespace MarketPulse.BusinessLogic.Common
{
    /// <summary>
    /// This class represents an accreditation that a shopper must complete before being allowed to perform shops for the client the accreditation represents.
    /// </summary>
    [Serializable]
    [Csla.Server.ObjectFactory("MarketPulse.DataAccess.Factory.AccreditationFactory, MarketPulse.DataAccess.Factory", "FetchInfo")]
    public class AccreditationInfo : MarketPulseReadOnlyBase<AccreditationInfo>
    {      

        #region Constructors

            /// <summary>
            /// default constructor is private in order to (try to) enforce construction
            /// only via the static factory methods provided.
            /// </summary>
            private AccreditationInfo()
            {
            }

        #endregion

        #region Methods

            #region Factory Methods

                /// <summary>
                /// Gets an AccreditationInfo object described by the Guid supplied (via the DataPortal client proxy)
                /// </summary>
                /// <param name="guid">The Guid of the Accreditation to retrieve</param>
                /// <returns>The populated AccreditationInfo object</returns>
                public static AccreditationInfo Get(Guid guid)
                {
                    return DataPortal.Fetch<AccreditationInfo>(new SingleCriteria<Guid>(guid));
                }

                /// <summary>
                /// Gets an AccreditationInfo object described by the Guid and VersionID supplied (via the DataPortal client proxy)
                /// </summary>
                /// <param name="guid">The Guid of the Accreditation to retrieve</param>
                /// /// <param name="versionID">The VersionID of the Accreditation to retrieve</param>
                /// <returns>The populated AccreditationInfo object</returns>                        
                public static AccreditationInfo Get(Guid guid, long versionID)
                {
                    return DataPortal.Fetch<AccreditationInfo>(new UniqueAccreditationCriteria(guid, versionID));
                }

            #endregion

            #region Business Process Methods

                /// <summary>
                /// Method used to retrieve the number of attempts (by a specific user) to complete an Accreditation successfully
                /// </summary>
                /// <param name="userGUID">The unique identifier for the user in question</param>
                /// <returns>The number of attempts</returns>
                public int GetFailedAttemptsByUser(Guid userGUID)
                {
                    return Attempts.GetAttemptsByUser(this.GUID.Value, userGUID, false);
                }

                /// <summary>
                /// Method used to determine if a specific user has completed an Accreditation successfully
                /// </summary>
                /// <param name="userGUID">The unique identifier for the user in question</param>
                /// <returns>Whether the user in question has successfully been accredited for this Accreditation</returns>
                public bool IsUserAccredited(Guid userGUID)
                {
                    return (Attempts.GetAttemptsByUser(this.GUID.Value, userGUID, true) > 0);
                }

            #endregion

        #endregion

            #region Properties

                /// <summary>
                /// The Version ID of this Accreditation. When used in conjunction with an AccreditationGUID, this
                /// uniquely identifies a given Accreditation.
                /// </summary>
                public static PropertyInfo<long> VersionIDProperty = RegisterProperty<long>(p => p.VersionID);
                /// <summary>
                /// The Version ID of this Accreditation. When used in conjunction with an AccreditationGUID, this
                /// uniquely identifies a given Accreditation.
                /// </summary>
                public long VersionID
                {
                    get { return GetProperty(VersionIDProperty); }                    
                }

                /// <summary>
                /// The GUID of the company (BusinessObject) that this Accreditation belongs to 
                /// </summary>
                public static PropertyInfo<Nullable<Guid>> CompanyGUIDProperty = RegisterProperty<Nullable<Guid>>(p => p.CompanyGUID);
                /// <summary>
                /// The GUID of the company (BusinessObject) that this Accreditation belongs to 
                /// </summary>
                public Nullable<Guid> CompanyGUID
                {
                    get { return GetProperty(CompanyGUIDProperty); }
                }

                /// <summary>
                /// The GUID of the component (BusinessObject) that this Accreditation is associated with
                /// </summary>
                public static PropertyInfo<Nullable<Guid>> ComponentGUIDProperty = RegisterProperty<Nullable<Guid>>(p => p.ComponentGUID);
                /// <summary>
                /// The GUID of the component (BusinessObject) that this Accreditation is associated with
                /// </summary>
                public Nullable<Guid> ComponentGUID
                {
                    get { return GetProperty(ComponentGUIDProperty); }
                }

                /// <summary>
                /// A human readable title for this Accreditation
                /// </summary>
                public static PropertyInfo<string> AccreditationTitleProperty = RegisterProperty<string>(p => p.Title);
                /// <summary>
                /// A human readable title for this Accreditation
                /// </summary>
                public string Title
                {
                    get { return GetProperty(AccreditationTitleProperty); }
                }

                /// <summary>
                /// A human readable description for this Accreditation
                /// </summary>
                public static PropertyInfo<string> AccreditationDescriptionProperty = RegisterProperty<string>(p => p.Description);
                /// <summary>
                /// A human readable description for this Accreditation
                /// </summary>
                public string Description
                {
                    get { return GetProperty(AccreditationDescriptionProperty); }
                }

                /// <summary>
                /// The XML document that describes the Accreditation.
                /// Sadly, the property type is required to be a string because XElement is not marked
                /// [Serializable] and therefore cannot be used with the Csla framework.
                /// </summary>
                public static PropertyInfo<string> AccreditationXMLProperty = RegisterProperty<string>(p => p.AccreditationXML);
                /// <summary>
                /// The XML document that describes the Accreditation.
                /// Sadly, the property type is required to be a string because XElement is not marked
                /// [Serializable] and therefore cannot be used with the Csla framework.
                /// </summary>
                public System.Xml.Linq.XElement AccreditationXML
                {
                    get { return System.Xml.Linq.XElement.Parse(GetProperty(AccreditationXMLProperty)); }                   
                }

                /// <summary>
                /// The minimum percentage requried for the Accreditation to be considered passed.
                /// </summary>
                public static PropertyInfo<decimal> PassPercentageProperty = RegisterProperty<decimal>(p => p.PassPercentage);
                /// <summary>
                /// The minimum percentage requried for the Accreditation to be considered passed.
                /// </summary>
                public decimal PassPercentage
                {
                    get { return GetProperty(PassPercentageProperty); }
                }

                /// <summary>
                /// The maximum amount of attempts allowed for this Accreditation.
                /// </summary>
                public static PropertyInfo<int> MaxAttemptsProperty = RegisterProperty<int>(p => p.MaxAttempts);
                /// <summary>
                /// The maximum amount of attempts allowed for this Accreditation.
                /// </summary>
                public int MaxAttempts
                {
                    get { return GetProperty(MaxAttemptsProperty); }
                }

                /// <summary>
                /// Whether or not a summary should be displayed for this Accreditation.
                /// </summary>
                public static PropertyInfo<bool> ShowSummaryProperty = RegisterProperty<bool>(p => p.ShowSummary);
                /// <summary>
                /// Whether or not a summary should be displayed for this Accreditation.
                /// </summary>
                public bool ShowSummary
                {
                    get { return GetProperty(ShowSummaryProperty); }
                }    

                /// <summary>
                /// The date and time when the Accreditation becomes current (in use)
                /// </summary>
                public static PropertyInfo<SmartDate> EffectiveStartDateTimeProperty = RegisterProperty<SmartDate>(p => p.EffectiveStartDateTime);
                /// <summary>
                /// The date and time when the Accreditation becomes current (in use)
                /// </summary>
                public SmartDate EffectiveStartDateTime
                {
                    get { return GetProperty(EffectiveStartDateTimeProperty); }
                }

                /// <summary>
                /// The date and time when the Accreditation ceases to be current (no longer in use)
                /// </summary>
                public static PropertyInfo<SmartDate> EffectiveEndDateTimeProperty = RegisterProperty<SmartDate>(p => p.EffectiveEndDateTime);
                /// <summary>
                /// The date and time when the Accreditation ceases to be current (no longer in use)
                /// </summary>
                public SmartDate EffectiveEndDateTime
                {
                    get { return GetProperty(EffectiveEndDateTimeProperty); }
                }

                #region Association Properties (Related Objects)

                    /// <summary>A collection of Accreditation attempts associated with this Accreditation</summary>
                    public static PropertyInfo<UserAccreditationList> UserAccreditationListProperty = RegisterProperty<UserAccreditationList>(p => p.Attempts);
                    /// <summary>A collection of Accreditation attempts associated with this Accreditation</summary>
                    private UserAccreditationList Attempts
                    {
                        get
                        {
                            // If the property hasn't been loaded yet
                            if (!FieldManager.FieldExists(UserAccreditationListProperty))
                            {
                                // Load the property
                                LoadProperty(UserAccreditationListProperty, UserAccreditationList.Get(this.GUID.Value));
                                return ReadProperty(UserAccreditationListProperty);
                            }
                            else
                            {
                                // Return the current property
                                return GetProperty(UserAccreditationListProperty);
                            }
                        }
                    }

                #endregion


        #endregion
    }
}
